package xx.services.entity.rest;

import java.io.ByteArrayInputStream;
import java.io.OutputStream;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.RowSet;
import javax.ws.rs.DELETE;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;

import xx.db.sql.Cnd;
import xx.db.sql.Select;
import xx.db.sql.Table;
import xx.entity.bas.Category;
import xx.entity.bas.CategoryLink;
import xx.entity.bas.Entity;
import xx.entity.bas.EntityExt;
import xx.entity.bas.EntityExtDefined;
import xx.entity.bas.NewsRule;
import xx.entity.bas.ProjectPay;
import xx.entity.datum.Type;
import xx.entity.manage.SystemConfig;
import xx.entity.task.NewsJob;
import xx.entity.util.Sign;
import xx.services.Passport;
import xx.services.entity.inter.ICategoryInterface;
import xx.services.util.Constants;
import xx.services.util.Results;
import xx.util.Arr;
import xx.util.string.Format;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

/**
 * 分类服务接口<br>
 * 
 * @Path (Constants.RESTFUL_ROOT_PATH + "/category")
 * @author dengjinye,2010-12-18 $LastChangedDate$ $Author$
 */
@Path(Constants.RESTFUL_ROOT_PATH + "/category")
public class CategoryRest extends Passport implements ICategoryInterface
{

    private Entity entity;

    protected Category category;

    public CategoryRest(@Context
    HttpServletRequest request)
    {
        super(request);
        entity = new Entity(qr, owner);
        category = new Category(qr, owner);
    }

    /**
     * 指定在某分类{category_id}下增加子分类。<br>
     * 
     * @POST
     * @Path ("/{category_id}")
     * @param categoryId
     *            -@PathParam("category_id") 分类ID，必须大于0
     * @param name
     *            -@FormParam("name") 分类名称
     * @param description
     *            -@FormParam("description") 描述
     * @return 新增Category的JSON字符串数据
     */
    @POST
    @Path("/{category_id}")
    public String addCategory(@PathParam("category_id")
    long categoryId, @FormParam("keyword")
    String keyword, @FormParam("name")
    String name, @FormParam("description")
    String description)
    {
        try
        {
            Category parentCategory = new Category(qr, owner);
            parentCategory.setCategoryId(categoryId);
            parentCategory.load();

            RowSet rs = parentCategory.getRoots();
            List<Category> list = category.rsToList(rs);
            Category root = list.get(0);

            Type type = new Type(qr, owner);
            type.setCategoryId(root.getCategoryId());

            category.setKeyword(keyword).setSign(root.getSign());

            long insertId = category.setParentId(categoryId).setName(name).setDescription(description).insert();

            // 将父category的横向扩展属性定义值复制给新的cagegory
            EntityExtDefined entityExtDefined = new EntityExtDefined(qr, owner);
            entityExtDefined.setCategoryId(categoryId).load();
            entityExtDefined.setCategoryId(insertId).insert();

            return ok(category);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 指定在某分类{category_id}下增加实体。<br>
     * 
     * @POST
     * @Path ("/{category_id}/entity")-@PathParam("category_id") 指定分类ID
     * @param title
     *            -@FormParam("title") 标题
     * @param content
     *            -@FormParam("content") 内容
     * @param url
     *            -@FormParam("url") URL地址
     * @param fileId
     *            -@FormParam("file_id") 指定关联文件ID
     * @param tags
     *            -@FormParam("tags") 实体tag标签，多个tag标签用空格“ ”隔开
     * @param value
     *            -@FormParam("value") 实体扩展属性的json数据 add by dengjinye 20130512
     * @return 新增的实体
     * @author dengjinye,2010-12-6
     */
    @POST
    @Path("/{category_id}/entity")
    public String addEntity(@PathParam("category_id")
    long categoryId, @FormParam("title")
    String title, @FormParam("content")
    String content, @FormParam("url")
    String url, @FormParam("file_id")
    long fileId, @FormParam("tags")
    String tags, @FormParam("value")
    String value)
    {
        try
        {
            CategoryLink cl = new CategoryLink(qr, owner);
            cl.setCategoryId(categoryId);
            int islock = (getParameter(Entity.ISLOCK) != null && getParameter(Entity.ISLOCK).isEmpty()) ? 0 : Integer.valueOf(getParameter(Entity.ISLOCK));
            int ontop = (getParameter(Entity.ONTOP) != null && getParameter(Entity.ONTOP).isEmpty()) ? 0 : Integer.valueOf(getParameter(Entity.ONTOP));
            long entityId = entity.setTitle(title).setContent(content).setUrl(url).setFileId(fileId).setIslock(islock).setOntop(ontop).insert();

            // 新增entity扩展属性
            if (!value.isEmpty())
            {
                JsonParser parser = new JsonParser();
                JsonArray ja = parser.parse(value).getAsJsonArray();
                String typeIdArr = "";
                for (JsonElement je : ja)
                {
                    JsonObject jo = je.getAsJsonObject();
                    long typeIdInJson = jo.get("type_id").getAsLong();
                    typeIdArr = typeIdArr + typeIdInJson + "_";
                }
                typeIdArr = typeIdArr.substring(0, typeIdArr.lastIndexOf("_"));
                DatumRest dr = new DatumRest(request);
                dr.addByTypeId(entityId, typeIdArr, value);
            }

            cl.setEntityId(entityId).setCategoryId(categoryId);
            System.out.println("category link is " + cl.toString());
            cl.insert();

            // 插入横向扩展属性 add by dengjinye 20130521
            EntityExtDefined entityExtDefined = new EntityExtDefined(qr, owner);
            entityExtDefined.setCategoryId(categoryId).load(EntityExtDefined.USED_FIELDS);
            String[] usedFieldsArr = entityExtDefined.getUsedFields().split(",");
            EntityExt ext = new EntityExt(qr, owner);
            for (String field : usedFieldsArr)
            {
                String v = getParameter(field);
                if (v != null && !v.isEmpty())
                {
                    ext.setValue(field, v);
                }
            }
            ext.setEntityId(entityId);
            ext.insert();

            addUrlLog(String.valueOf(entityId), String.valueOf(entityId));

            return ok(entityId);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 描述：删除分类{category_id}。<br>
     * 注：删除此分类时，连同子分类也要一起删除。
     * 
     * @DELETE
     * @Path ("/{category_id}")
     * @param categoryId
     *            -@PathParam("category_id") 分类ID，多个分类ID用“_”连接
     * @return
     */
    @DELETE
    @Path("/{category_id}")
    public String deleteCategory(@PathParam("category_id")
    long categoryId)
    {
        try
        {
            category.setCategoryId(categoryId);
            return ok(category.delete());
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 指定获取单个分类{category_id}的信息。<br>
     * 包含与此分类关联的附件类型、tag等。
     * 
     * @GET HTTP请求类型
     * @Path ("/{category_id}")
     * @param categoryId
     *            -@PathParam("category_id") 分类ID
     * @return Category的JSON字符串数据
     */
    @GET
    @Path("/{category_id}")
    public String getCategory(@PathParam("category_id")
    long categoryId)
    {
        try
        {
            category.setCategoryId(categoryId).load();
            return ok(category);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 指定获取某分类{category_id}下的第一级节点。<br>
     * 
     * @GET
     * @Path ("/{category_id}/children")
     * @param categoryId
     *            -@PathParam("category_id") 分类ID
     * @return category列表
     * @throws Exception
     *             String 下午09:28:30
     * @author dengjinye
     */
    @GET
    @Path("/{category_id}/children")
    public String getCategoryChildren(@PathParam("category_id")
    long categoryId)
    {
        try
        {
            RowSet rs = category.setCategoryId(categoryId).getChildren();
            return ok(rs);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 获取某分类{category_id}下的实体列表。
     * 
     * @GET
     * @Path ("/{category_id}/entity")
     * @param categoryId
     * @param sign
     *            分类标志，当categoryId为0时生效
     * @param entity
     *            实体名称，如产品为(product)、文档为(document)等，与sign的功能是一样的，当sign为0时，此参数生效
     * @param onlyCurCategory
     *            是否只获取当前分类下的实体<br>
     *            默认为false，获取当前分类下的所有子分类下的实体<br>
     * @return String 下午09:45:49
     * @author dengjinye
     */
    @GET
    @Path("/{category_id}/entity")
    public String getEntityList(@PathParam("category_id")
    long categoryId, @QueryParam("entity")
    String entity, @DefaultValue("true")
    @QueryParam("only_cur_category")
    boolean onlyCurCategory)
    {
        try
        {
            // 禁止无条件根据sign查询（从性能方面考虑）
            if (categoryId == 0 && (condition == null || condition.trim().equals("")))
                return ok("请输入查询条件进行查询！");

            category.setCategoryId(categoryId);
            if (categoryId == 0)
            {
                int sign = Format.strToInt(this.getParameter("sign"));
                if (sign > 0)
                    category.setSign(sign);
                else if (!Format.isEmpty(entity))
                    category.setSign(Sign.signOf(entity).ordinal());
                else
                    return error("非法访问");
            }

            List<Entity> rs = null;
            Map<String, Object> map = new HashMap<String, Object>();
            category.setCategoryId(categoryId);

            if (categoryId > 0)
            {
                // 金融网列表的更多需要目录名称
                category.load("name");
                map.put(Category.NAME, category.getName());
            }

            String tempCodition = condition;
            if (condition != null && !"".equals(condition))
            {
                tempCodition = URLDecoder.decode(condition, "UTF-8"); // 由于url中的中文需要转码，所以这里需要解码
            }

            // if(SystemConfig.systemName.equals(SystemConfig.CGS))
            // updatePayInfoForSearch(tempCodition, onlyCurCategory); //
            // 车管所系统特有逻辑，如果不是车管所系统，此调用无任何影响

            if (!onlyCurCategory)
            {
                rs = category.getEntityList(pageSize, pageNo, tempCodition, orderField, fields, EntityExtDefined.SHOW_FIELDS);
                // 如果是获取第一页的数据，则同时返回总数
                if (isTotal)
                {
                    map.put(Constants.TOTAL, category.getEntityCount(tempCodition));
                }
            }
            else
            {
                rs = category.getCurrentEntityList(pageSize, pageNo, tempCodition, orderField, fields, EntityExtDefined.SHOW_FIELDS);
                // 如果是获取第一页的数据，则同时返回总数
                if (isTotal)
                {
                    map.put(Constants.TOTAL, category.getCurrentEntityCount(tempCodition));
                }
            }

            return ok(rs, map);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 更新查询项目的年支付信息（只在查询时起效，车管所系统特有）
     * 
     * @param condition
     * @param onlyCurCategory
     * @throws SQLException
     */
    // private void updatePayInfoForSearch(String condition, boolean onlyCurCategory) throws
    // SQLException
    // {
    // SystemConfig systemConfig = new SystemConfig(qr, owner);
    // systemConfig.setName(SystemConfig.SYSTEM_NAME).load(SystemConfig.VALUE);
    // if (!SystemConfig.CGS.equals(systemConfig.getValue()))
    // return;
    //
    // // 当sign=1的时候（项目模块），才需要更新年支付信息
    // if (category.getCategoryId() != 0 && category.getSign() == 0)
    // {
    // category.load(Category.SIGN);
    // }
    // if (category.getSign() != 1)
    // return;
    //
    // ProjectPay projectPay = new ProjectPay(qr, owner);
    // int year;
    // if (condition != null && condition.contains("str22 like"))
    // {
    // year = Integer.parseInt(condition.substring(condition.indexOf("str22 like '%") + 13,
    // condition.indexOf("str22 like '%") + 17));
    // }
    // else
    // // 如果没有输入“支付年份”作为查询条件，则默认更新当年的支付信息
    // {
    // Calendar cal = Calendar.getInstance();
    // year = cal.get(Calendar.YEAR);
    // }
    // if (category.getCategoryId() == 0 && category.getSign() > 0) // 根据sign进行更新
    // {
    // projectPay.updatePayInfoForSearch(year, condition, category.getSign());
    // }
    // else
    // { // 根据categoryId进行更新
    // String categoryIds;
    // if (onlyCurCategory == true)
    // categoryIds = String.valueOf(category.getCategoryId());
    // else
    // {
    // long[] childrenIds = category.getAllChildrenIds();
    // String ids = category.getCategoryId() + (childrenIds != null && childrenIds.length > 0 ? ","
    // + Arr.toString(childrenIds) : "");
    // categoryIds = ids;
    // }
    // projectPay.updatePayInfoForSearch(year, condition, categoryIds);
    // }
    // }

    /**
     * 统计指定字段的总计
     * 
     * @param categoryId
     * @param entity
     * @param onlyCurCategory
     *            是否只查询当前category
     * @param sumFields
     *            需要统计的entity的基本字段
     * @param sumEntityExtFields
     *            需要统计的entityExt的字段
     * @author dengjinye 2013-07-27
     * @return
     */
    @GET
    @Path("/{category_id}/entity/sumtotal")
    public String getEntitySumTotal(@PathParam("category_id")
    long categoryId, @QueryParam("entity")
    String entity, @DefaultValue("true")
    @QueryParam("only_cur_category")
    boolean onlyCurCategory, @QueryParam("sumFields")
    String sumFields, @QueryParam("sumEntityExtFields")
    String sumEntityExtFields)
    {
        try
        {
            // 禁止无条件根据sign查询（从性能方面考虑）
            if (categoryId == 0 && (condition == null || condition.trim().equals("")))
                return ok(null);

            category.setCategoryId(categoryId);
            if (categoryId == 0)
            {
                int sign = Format.strToInt(this.getParameter("sign"));
                if (sign > 0)
                    category.setSign(sign);
                else if (!Format.isEmpty(entity))
                    category.setSign(Sign.signOf(entity).ordinal());
                else
                    return error("非法访问");
            }

            Map<String, Object> rs = null;
            category.setCategoryId(categoryId);

            String tempCodition = condition;
            if (condition != null && !"".equals(condition))
            {
                tempCodition = URLDecoder.decode(condition, "UTF-8"); // 由于url中的中文需要转码，所以这里需要解码
            }

            if (!onlyCurCategory)
            {
                rs = category.getEntityColumnSumList(tempCodition, sumFields == null ? "" : sumFields, sumEntityExtFields == null ? "" : sumEntityExtFields);
            }
            else
            {
                rs = category.getCurrentEntityColumnSumList(tempCodition, sumFields == null ? "" : sumFields, sumEntityExtFields == null ? "" : sumEntityExtFields);
            }
            logger.info(rs.toString());
            return ok(rs);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 导出某分类{category_id}下的实体列表。
     * 
     * @GET
     * @Path ("/{category_id}/export")
     * @param categoryId
     * @param sign
     *            分类标志，当categoryId为0时生效
     * @param entity
     *            实体名称，如产品为(product)、文档为(document)等，与sign的功能是一样的，当sign为0时，此参数生效
     * @param onlyCurCategory
     *            是否只获取当前分类下的实体<br>
     *            默认为false，获取当前分类下的所有子分类下的实体<br>
     * @return String 下午09:45:49
     * @author dengjinye
     */
    @GET
    @Path("/{category_id}/export")
    public String exportEntityList(@Context
    HttpServletResponse response, @PathParam("category_id")
    long categoryId, @QueryParam("sign")
    int sign, @QueryParam("entity")
    String entity, @QueryParam("only_cur_category")
    boolean onlyCurCategory, @QueryParam("sumFields")
    String sumFields, @QueryParam("sumEntityExtFields")
    String sumEntityExtFields)
    {
        try
        {
            category.setCategoryId(categoryId);
            if (categoryId == 0)
            {
                if (sign > 0)
                    category.setSign(sign);
                else if (!Format.isEmpty(entity))
                    category.setSign(Sign.signOf(entity).ordinal());
                else
                {
                    logger.error("缺少 categoryId");
                    return error("缺少 categoryId");
                }
            }

            List<Entity> rs = null;
            if (categoryId > 0)
            {
                category.setCategoryId(categoryId);
                category.load(Category.NAME);
            }
            else
            {
                category.setName("全局查询结果");
            }
            int expPageSize = Integer.MAX_VALUE - 2;
            int expPageNo = 1;

            String tempCodition = condition;
            if (!onlyCurCategory)
            {
                if (tempCodition != null && !"".equals(tempCodition))
                {
                    tempCodition = URLDecoder.decode(tempCodition, "UTF-8"); // 由于url中的中文需要转码，所以这里需要解码
                    rs = category.getEntityList(expPageSize, expPageNo, tempCodition, orderField, fields, EntityExtDefined.USED_FIELDS);
                }
                else
                {
                    rs = category.getEntityList(expPageSize, expPageNo, condition, orderField, fields, EntityExtDefined.USED_FIELDS);
                }
            }
            else
            {
                rs = category.getCurrentEntityList(expPageSize, expPageNo, condition, orderField, fields, EntityExtDefined.USED_FIELDS);
            }

            if (rs.size() == 0)
            {
                return error("没有数据，导出操作被终止！");
            }

            // 导出文件
            response.reset();
            // response.setContentType("application/x-download;charset=utf-8");//iso-8859-1
            response.setContentType("application/x-msdownload");// iso-8859-1
            // response.setHeader("Content-Disposition", "attachment; filename=\"" +
            // URLEncoder.encode(category.getName() + ".cvs", "utf-8") + "\"");
            String agent = request.getHeader("User-Agent");
            boolean isMSIE = (agent != null && agent.indexOf("MSIE") != -1);
            String fileName = category.getName() + ".cvs";
            if (isMSIE)
            {
                fileName = URLEncoder.encode(fileName, "UTF-8");
            }
            else
            {
                fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            }
            response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
            OutputStream out = response.getOutputStream();
            StringBuffer sb = new StringBuffer();

            EntityExtDefined entityExtDefined = new EntityExtDefined(qr, owner);
            entityExtDefined.setCategoryId(categoryId == 0 ? (0 - category.getSign()) : category.getCategoryId()).load(EntityExtDefined.USED_FIELDS, EntityExtDefined.CONTENT);

            // 获取需要导出的字段名和字段信息
            String content = entityExtDefined.getContent();
            JsonParser parser = new JsonParser();
            JsonObject jo = parser.parse(content).getAsJsonObject();
            JsonObject attribute = jo.get(EntityExtDefined.ATTRIBUTE).getAsJsonObject();
            String[] usedFields = entityExtDefined.getUsedFields().split(",");

            // 填写报表字段名
            for (int i = 0; i < usedFields.length; i++)
            {
                sb.append(attribute.get(usedFields[i]).getAsJsonObject().get(EntityExtDefined.NAME).getAsString()).append("\t");
            }
            sb.append("\n");

            // 填写输出内容
            for (int i = 0; i < rs.size(); i++)
            {
                Entity e = rs.get(i);
                for (int j = 0; j < usedFields.length; j++)
                {
                    String field = usedFields[j];
                    Object value = e.getOtherValue(field);
                    if (value != null)
                    {
                        if (value instanceof Timestamp)
                        {
                            sb.append(value.toString().replace("-", "").substring(0, 8));
                        }
                        else
                        {
                            sb.append(value.toString());
                        }
                    }
                    sb.append("\t");
                }
                sb.append("\n");
            }

            // 获取相关统计金额
            if ((sumFields != null && !sumFields.isEmpty()) || (sumEntityExtFields != null && !sumEntityExtFields.isEmpty()))
            {
                if (condition != null && !"".equals(condition))
                {
                    tempCodition = URLDecoder.decode(condition, "UTF-8"); // 由于url中的中文需要转码，所以这里需要解码
                }
                Map<String, Object> sumMap = new HashMap<String, Object>();
                if (!onlyCurCategory)
                {
                    if (tempCodition != null && !"".equals(tempCodition))
                    {
                        sumMap = category.getEntityColumnSumList(tempCodition, sumFields == null ? "" : sumFields, sumEntityExtFields == null ? "" : sumEntityExtFields);
                    }
                    else
                    {
                        sumMap = category.getEntityColumnSumList(tempCodition, sumFields == null ? "" : sumFields, sumEntityExtFields == null ? "" : sumEntityExtFields);
                    }
                }
                else
                {
                    sumMap = category.getCurrentEntityColumnSumList(tempCodition, sumFields == null ? "" : sumFields, sumEntityExtFields == null ? "" : sumEntityExtFields);
                }

                if (SystemConfig.systemName.equals(SystemConfig.CGS) && sign == 1)// 填写总计金额内容
                {
                    sb.append("\n").append("\n").append("指定年份支付金额总计").append("\t").append(sumMap.get(ProjectPay.PAYPRICE)).append("\n");
                }
            }

            ByteArrayInputStream in = new ByteArrayInputStream(sb.toString().getBytes("GB2312"));
            int i = 0;
            byte[] buffer = new byte[1024];

            while ((i = in.read(buffer)) != -1)
            {
                out.write(buffer, 0, i);
            }
            out.close();
            out.flush();
            in.close();

            return ok("导出成功");
        }
        catch (Exception e)
        {
            e.printStackTrace();
            String errorMsg = "导出过程中出错，请联系管理员";
            Results.createErrForDownOrExp(response, errorMsg);
            return error(e);
        }
    }

    /**
     * 把分类{category_id}移动到分类{category_id2}下。<br>
     * 
     * @PUT
     * @Path ("/{category_id1}/to/{category_id2}")
     * @param categoryId1
     *            -@PathParam("category_id1")
     * @param categoryId2
     *            -@PathParam("category_id2")
     * @return
     * @throws Exception
     *             String 下午09:33:50
     * @author dengjinye
     */
    @PUT
    @Path("/{category_id1}/to/{category_id2}")
    public String moveCategory(@PathParam("category_id1")
    long categoryId1, @PathParam("category_id2")
    long categoryId2)
    {
        try
        {
            category.setCategoryId(categoryId1).move(categoryId2);
            return ok(true);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 把分类{category_id1}排到分类{category_id2}<br>
     * 的前边或后边（当{category_id2}>0时表示排到{category_id2}的后边，当<br>
     * {category_id2}<0时表示排到{category_id2}的前边），注：{category_id2}<0<br>
     * 就是在{category_id2}前加负号(-)。<br>
     * 
     * @PUT
     * @Path ("/{category_id1}/sort/{category_id2}")
     * @param categoryId1
     *            -@PathParam("category_id1")
     * @param categoryId2
     *            -@PathParam("category_id2")
     * @return String 下午09:52:56
     * @author dengjinye
     */
    @PUT
    @Path("/{category_id1}/sort/{category_id2}")
    public String sortCategory(@PathParam("category_id1")
    long categoryId1, @PathParam("category_id2")
    long categoryId2)
    {
        try
        {
            if (categoryId2 > 0)
            {
                category.setCategoryId(categoryId1).sortAfter(categoryId2);
            }
            else
            {
                category.setCategoryId(categoryId1).sortBefore(categoryId2);
            }
            return ok(true);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 修改分类{category_id}。<br>
     * 
     * @PUT
     * @Path ("/{category_id}")
     * @param categoryId
     *            -@PathParam("category_id") 分类ID
     * @param name
     *            -@FormParam("name") 分类名称
     * @param description
     *            -@FormParam("description") 描述
     * @return 新增Category的JSON字符串数据
     */
    @PUT
    @Path("/{category_id}")
    public String updateCategory(@PathParam("category_id")
    long categoryId, @FormParam("name")
    String name, @FormParam("keyword")
    String keyword, @FormParam("description")
    String description)
    {
        try
        {
            category.setCategoryId(categoryId).setName(name).setDescription(description);
            category.setKeyword(keyword);
            category.update(Category.NAME, Category.DESCRIPTION, Category.KEYWORD);
            return ok(category);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    @POST
    @Path("/{category_id}/rule")
    public String addNewsRule(@PathParam("category_id")
    long categoryId, @FormParam("title_rule")
    String titleRule, @FormParam("content_rule")
    String contentRule, @FormParam("url")
    String url, @FormParam("encoding")
    String encoding)
    {
        try
        {
            NewsRule nr = new NewsRule(qr, owner);
            nr.setCategoryId(categoryId).setUrl(url).setTitleRule(titleRule).setContentRule(contentRule).setEncoding(encoding);
            nr.insert();
            return ok(nr);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    @DELETE
    @Path("/{category_id}/rule/{rule_ids}")
    public String deleteNewsRule(@PathParam("category_id")
    long categoryId, @PathParam("rule_ids")
    String ruleIds)
    {
        try
        {
            long[] ruleIdArr = Arr.toLongArray(ruleIds, "_");
            for (long ruleId : ruleIdArr)
            {
                NewsRule nr = new NewsRule(qr, owner);
                nr.setRuleId(ruleId);
                nr.delete();
            }
            return ok(true);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    @GET
    @Path("/{category_id}/rule")
    public String getNewsRule(@PathParam("category_id")
    long categoryId)
    {
        try
        {
            category.setCategoryId(categoryId);
            return ok(category.getNewsRuleRowSet());
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    @GET
    @Path("/{category_id}/rule/{rule_id}")
    public String getNewsRule(@PathParam("category_id")
    long categoryId, @PathParam("rule_id")
    long ruleId)
    {
        try
        {
            NewsRule rule = new NewsRule(qr, owner);
            rule.setPK(ruleId);
            rule.load();
            return ok(rule);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    @PUT
    @Path("/{category_id}/rule/{rule_id}")
    public String updateNewsRule(@PathParam("category_id")
    long categoryId, @FormParam("title_rule")
    String titleRule, @FormParam("content_rule")
    String contentRule, @FormParam("url")
    String url, @PathParam("rule_id")
    long ruleId, @FormParam("encoding")
    String encoding)
    {
        try
        {
            NewsRule nr = new NewsRule(qr, owner);
            nr.setRuleId(ruleId).setTitleRule(titleRule).setContentRule(contentRule).setUrl(url).setEncoding(encoding);
            nr.update(NewsRule.URL, NewsRule.TITLE_RULE, NewsRule.CONTENT_RULE, NewsRule.ENCODING);
            return ok(nr);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    @POST
    @Path("/rule/{rule_id}")
    public String excuteRule(@PathParam("rule_id")
    String ruleIds)
    {
        try
        {
            Select select = new Select(qr, owner);

            List<NewsRule> rules = select.from(NewsRule.class).where(Cnd.instance(qr, NewsRule.RULE_ID, Cnd.IN, Arr.toLongArray(ruleIds, "_"))).go();
            NewsJob nj = new NewsJob();
            for (NewsRule rule : rules)
            {
                nj.reptile(rule, false);
            }
            return ok(true);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    //
    // @GET
    // @Path("/init")
    // public String initCategory()
    // {
    // try
    // {
    // Select select = new Select(qr, owner);
    // select.from(Category.class).where(qr.cnd(Category.PARENT_ID, "=", 0));
    // List<Category> list = select.go();
    // if (list != null)
    // {
    // for (Category c : list)
    // c.updatePath();
    // }
    // return ok(true);
    // }
    // catch (Exception e)
    // {
    // return error(e);
    // }
    // }

    /**
     * 描述：获取category的档案基础信息，包含扩展属性. <br>
     * 1.获取category_id对应的所有档案 <br>
     * 2.获取category_id下指定分类({type_id|keyword})对应的档案属性。 输入： 输出：档案JSON数据 [ { detail_id, category_id,
     * type_id, rule, error, single, keyword, [ { value_id, attribute_id, title, value, rule, error,
     * datatype, opvalue } ] } ]
     * 
     * @GET
     * @Path("/{category_id /datum")<br>
     * @param categoryId
     * @return
     * @author dengjinye,2013-4-29
     */
    @GET
    @Path("/{category_id}/datum")
    public String getDatumByCategory(@PathParam("category_id")
    long categoryId)
    {
        try
        {
            Type type = new Type(qr, owner);
            type.setCategoryId(categoryId);
            List<? extends Table> list = type.getListByCategoryId();
            return ok(list);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 根据categoryId获取此目录中entity的横向属性定义字段
     * 
     * @GET
     * @Path("/{category_id ")/extdefined<br>
     * @param categoryId
     * @return
     * @author dengjinye,2013-5-21
     */
    @GET
    @Path("/{category_id}/extdefined")
    public String getExtDefinedByCategory(@PathParam("category_id")
    long categoryId)
    {
        try
        {
            EntityExtDefined entityExtDefined = new EntityExtDefined(qr, owner);

            if (categoryId == 0)
            {
                int sign = Format.strToInt(this.getParameter("sign"));
                categoryId = Integer.valueOf("-" + sign);
            }
            boolean isload = entityExtDefined.setCategoryId(categoryId).load();
            if (isload)
            {
                return ok(entityExtDefined);
            }
            else
            {

                return error("横向扩展属性定义数据出错，请联系相关维护人员");
            }
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

    /**
     * 更新categoryId的横向属性字段
     * 
     * @param categoryId
     * @param title
     *            横向属性title
     * @param showFields
     *            需要显示的字段，多个字段间用逗号“,”间隔
     * @return
     * @author dengjinye 2013-5-21
     */
    @PUT
    @Path("/{category_id}/extdefined")
    public String updateExtDefined(@PathParam("category_id")
    long categoryId, @QueryParam("title")
    String title, @QueryParam("show_fields")
    String showFields)
    {
        try
        {
            EntityExtDefined entityExtDefined = new EntityExtDefined(qr, owner);
            if (categoryId != 0)
                entityExtDefined.setCategoryId(categoryId);
            else
            {
                int sign = Format.strToInt(this.getParameter("sign"));
                categoryId = Integer.valueOf("-" + sign);
                entityExtDefined.setCategoryId(categoryId);
            }

            StringBuffer updateColumn = new StringBuffer();
            if (title != null && !title.isEmpty())
            {
                entityExtDefined.setTitle(title);
                updateColumn.append(EntityExtDefined.TITLE).append(",");
            }

            if (showFields != null && !showFields.isEmpty())
            {
                entityExtDefined.setShowFields(showFields);
                updateColumn.append(EntityExtDefined.SHOW_FIELDS).append(",");
            }

            String uc = updateColumn.toString();
            if (uc != null && !uc.isEmpty())
            {
                entityExtDefined.update(uc.split(","));
            }

            return ok(entityExtDefined);
        }
        catch (Exception e)
        {
            return error(e);
        }
    }

}
